<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Simulating DOM Events</title>
    <link rel="stylesheet" href="http://yui.yahooapis.com/3.4.0pr3/build/cssgrids/grids-min.css">
    <link rel="stylesheet" href="../assets/css/main.css">
    <link rel="stylesheet" href="../assets/vendor/prettify/prettify-min.css">
    <script src="../../build/yui/yui-min.js"></script>
</head>
<body>

<div id="doc">
    <h1>Simulating DOM Events</h1>

    
        <a href="#toc" class="jump">Jump to Table of Contents</a>
    

    <div class="yui3-g">
        <div id="main" class="yui3-u">
            <div class="content"><div class="intro">
    <p>
        When creating automated tests for your application or modules, you need
        to be able to mock user events.  The DOM supports creating native events
        that behave essentially the same as user generated events, though
        without the associated browser default behaviors (e.g. following a link
        on click).
    </p>
    <p>
        The <code>event-simulate</code> module adds the <code>Y.Event.simulate</code> method for
        working with raw DOM nodes, but for most cases, the
        <code>node-event-simulate</code> module is the right choice, since it allows you
        to call the <code>simulate</code> method directly from the <code>Node</code>.
    </p>
</div>

<h2 id="simulating-mouse-events">Simulating Mouse Events</h2>

<p>
    There are seven mouse events that can be simulated:
</p>

<ul>
  <li><code>click</code></li>
  <li><code>dblclick</code></li>
  <li><code>mousedown</code></li>
  <li><code>mouseup</code></li>
  <li><code>mouseover</code></li>
  <li><code>mouseout</code></li>
  <li><code>mousemove</code></li>
</ul>

<p>
    Each event is fired by calling <code>simulate()</code> and passing in two
    arguments: the type of event to fire and an optional object specifying
    additional information for the event. To simulate a click on the document's
    body element, for example, the following code can be used:
</p>

<pre class="code prettyprint">YUI().use(&#x27;node-event-simulate&#x27;, function(Y) {

    Y.one(&quot;body&quot;).simulate(&quot;click&quot;);
});</pre>


<p>
    This code simulates a click with all of the default properties on the
    <code>event</code> object. To specify additional information, such as the
    Shift key being down, the second argument must be used and the exact DOM
    name for the event property specified (there is browser-normalizing logic
    that translates these into browser-specific properties when necessary):
</p>

<pre class="code prettyprint">Y.one(&quot;body&quot;).simulate(&quot;click&quot;, { shiftKey: true });</pre>


<p>
    In this updated example, a click event is fired on the document's body
    while simulating that the Shift key is down.
</p>

<p>
    The extra properties to specify vary depending on the event being simulated
    and are limited to this list:
</p>

<dl>
    <dt><code>detail</code></dt>
        <dd>
            Indicates the number of times a button was clicked (DOM-compliant
            browsers only).
        </dd>

    <dt><code>screenX</code>, <code>screenY</code></dt>
        <dd>
            Coordinates of the mouse event in relation to the entire screen
            (DOM-compliant browsers only).
        </dd>

    <dt><code>clientX</code>, <code>clientY</code></dt>
        <dd>
            Coordinates of the mouse event in relation to the browser client
            area.
        </dd>

    <dt><code>ctrlKey</code>, <code>altKey</code>, <code>shiftKey</code>, <code>metaKey</code></dt>
        <dd>
            The state of the Ctrl, Alt, Shift, and Meta keys, respectively
            (true for down, false for up).
        </dd>

    <dt><code>button</code></dt>
        <dd>
            The button being used for the event, 0 for left (default), 1 for
            right, 2 for center.
        </dd>

    <dt><code>relatedTarget</code></dt>
        <dd>
            the element the mouse moved from (during a <code>mouseover</code> event) or to
            (during a <code>mouseout</code> event). 
        </dd>
</dl>

<pre class="code prettyprint">YUI().use(&#x27;node-event-simulate&#x27;, function(Y) {

    var node = Y.one(&quot;#myDiv&quot;);

    &#x2F;&#x2F;simulate a click Alt key down
    node.simulate(&quot;click&quot;, { altKey: true});

    &#x2F;&#x2F;simulate a double click with Ctrl key down
    node.simulate(&quot;dblclick&quot;, { ctrlKey: true });

    &#x2F;&#x2F;simulate a mouse over
    node.simulate(&quot;mouseover&quot;, { relatedTarget: document.body });

    &#x2F;&#x2F;simulate a mouse out
    node.simulate(&quot;mouseout&quot;, { relatedTarget: document.body });

    &#x2F;&#x2F;simulate a mouse down at point (100,100) in the client area
    node.simulate(&quot;mousedown&quot;, { clientX: 100, clientY: 100 });

    &#x2F;&#x2F;simulate a mouse up at point (100,100) in the client area
    node.simulate(&quot;mouseup&quot;, { clientX: 100, clientY: 100 });

    &#x2F;&#x2F;simulate a mouse move at point (200, 200) in the client area
    node.simulate(&quot;mousemove&quot;, { clientX: 200, clientY: 200 });
});</pre>


<h2 id="simulating-key-events">Simulating Key Events</h2>

<p>There are three key event simulations available:</p>

<ul>
    <li><code>keyup</code></li>
    <li><code>keydown</code></li>
    <li><code>keypress</code></li>
</ul>

<p>
    As with the mouse events, key events are simulated using
    <code>simulate()</code>. For <code>keyup</code> and <code>keydown</code>,
    the <code>keyCode</code> property must be specified; for
    <code>keypress</code>, the <code>charCode</code> property must be included.
    In many cases, <code>keyCode</code> and <code>charCode</code> may be the
    same value to represent the same key (97, for instance, represents the
    &quot;A&quot; key as well as being the ASCII code for the letter
    &quot;a&quot;). For example:
</p>

<pre class="code prettyprint">YUI().use(&#x27;node-event-simulate&#x27;, function(Y) {

    var node = Y.one(&quot;#myDiv&quot;);

    &#x2F;&#x2F;simulate a keydown on the A key
    node.simulate(&quot;keydown&quot;, { keyCode: 97 });

    &#x2F;&#x2F;simulate a keyup on the A key
    node.simulate(&quot;keyup&quot;, { keyCode: 97 });

    &#x2F;&#x2F;simulate typing &quot;a&quot;
    node.simulate(&quot;keypress&quot;, { charCode: 97 });
});</pre>


<p>
    Key events also support the <code>ctrlKey</code>, <code>altKey</code>,
    <code>shiftKey</code>, and <code>metaKey</code> event properties.
</p>
<p>
    <strong>Note:</strong> Due to differences in browser implementations, key
    events may not be simulated in the same manner across all browsers. For
    instance, when simulating a keypress event on a textbox, only Firefox will
    update the textbox with the new character of the key that was simulated to
    be pressed. For other browsers, the events are still registered and all
    event handlers are called, however, the textbox display and
    <code>value</code> property are not updated. These differences should go
    away as browser support for simulated events improves in the future.
</p>

<h2 id="simulating-ui-events">Simulating UI Events</h2>

<p>There are several UI event simulations available:</p>

<ul>
    <li><code>blur</code></li>
    <li><code>change</code></li>
    <li><code>focus</code></li>
    <li><code>resize</code></li>
    <li><code>scroll</code></li>
    <li><code>select</code></li>
</ul>

<p>
    As with the other events, UI events are simulated using
    <code>simulate()</code>. There are no properties that are required to
    simulate UI events as these events don't carry extra information. Some
    examples:
</p>

<pre class="code prettyprint">YUI().use(&#x27;node-event-simulate&#x27;, function(Y) {

    var node = Y.one(&quot;#myInput&quot;);

    &#x2F;&#x2F;simulate a change event
    node.simulate(&quot;change&quot;);

    &#x2F;&#x2F;simulate a select event
    node.simulate(&quot;select&quot;);
});</pre>


<h2 id="caveats-and-coming-soons">Caveats and Coming Soons</h2>

<h3 id="faking">Don't use simulation in user facing code</h3>

<p>
    Event simulation is for automated testing.  Your application should respond
    to real user events.  For reasons
    <a href="#only-what-you-ask-for">mentioned below</a>, it can be easy to get
    your application into a confused runtime state when some callbacks have
    been executed but not others.
</p>

<p>
    Typically, event simulation is sought to trigger certain callbacks.  If a
    function needs to respond to user action or be called programmatically, it
    should be written accordingly and called directly in the latter case.
    Often a better solution is to extract the core logic from the event handler
    into a separate function and call that method from the event handler and
    from the other part of the application that was going to use simulation.
</p>

<p>
    In some cases, simulation is wanted because there may be any number of
    subscriptions on a node, and all applicable callbacks should be triggered.
    If this is the case, investigate using <a
    href="../event-custom/index.html">custom events</a>, instead.
</p>

<p>
    The bottom line is, reliance on event simulation in production code is a
    warning sign that the architecture is not scaling.  The affected code
    should be refactored before it becomes a larger problem.
</p>

<h3 id="only-what-you-ask-for">Only what you ask for</h3>

<p>
    In many cases, events happen in groups (<code>mousedown</code>, <code>mouseup</code>, <code>click</code>, or
    <code>keydown</code>, <code>keyup</code>, <code>keypress</code>).  If you simulate an event that is
    typically part of a group or is often followed by other events, <em>the
    other events will NOT be generated</em> for free.
</p>

<p>
    For example, if you simulate a <code>click</code> event on a submit button, you only
    simulate the <code>click</code> event.  The preceding <code>mousedown</code> and <code>mouseup</code>, as
    well as the subsequently expected 'submit' are neither simulated or fired
    natively.
</p>

<h3 id="no-touch-events-yet">No touch events yet</h3>

<p>
    Currently, there's no support for simulating touch events or other events
    not noted explicitly above.
</p>

<h3 id="no-synthetic-event-simulation-yet">No synthetic event simulation yet</h3>

<p>
    The <a href="synths.html">Synthetic event system</a> doesn't yet support
    defining simulation. In most cases, though, synthetic events are triggered
    by other DOM events that can be simulated, so it's often possible to
    trigger them by simulating the underlying events.  But that ignores the
    point that synthetic events are supposed to mask that abstraction for your
    benefit.
</p>

<p>
    Support for synthetic event simulation is on the roadmap.
</p>
</div>
        </div>

        <div id="sidebar" class="yui3-u">
            
                <div id="toc" class="sidebox">
                    <div class="hd">
                        <h2 class="no-toc">Table of Contents</h2>
                    </div>

                    <div class="bd">
                        <ul class="toc">
<li>
<a href="#simulating-mouse-events">Simulating Mouse Events</a>
</li>
<li>
<a href="#simulating-key-events">Simulating Key Events</a>
</li>
<li>
<a href="#simulating-ui-events">Simulating UI Events</a>
</li>
<li>
<a href="#caveats-and-coming-soons">Caveats and Coming Soons</a>
<ul class="toc">
<li>
<a href="#faking">Don't use simulation in user facing code</a>
</li>
<li>
<a href="#only-what-you-ask-for">Only what you ask for</a>
</li>
<li>
<a href="#no-touch-events-yet">No touch events yet</a>
</li>
<li>
<a href="#no-synthetic-event-simulation-yet">No synthetic event simulation yet</a>
</li>
</ul>
</li>
</ul>
                    </div>
                </div>
            

            
                <div class="sidebox">
                    <div class="hd">
                        <h2 class="no-toc">Examples</h2>
                    </div>

                    <div class="bd">
                        <ul class="examples">
                            
                                
                                    <li data-description="Use the Event Utility to attach simple DOM event handlers.">
                                        <a href="basic-example.html">Simple DOM Events</a>
                                    </li>
                                
                            
                                
                                    <li data-description="Using the synthetic event API to create a DOM event that fires in response to arrow keys being pressed.">
                                        <a href="synth-example.html">Creating an Arrow Event for DOM Subscription</a>
                                    </li>
                                
                            
                                
                                    <li data-description="Supporting cross-device swipe gestures, using the event-move gesture events">
                                        <a href="swipe-example.html">Supporting A Swipe Left Gesture</a>
                                    </li>
                                
                            
                                
                            
                                
                            
                                
                            
                                
                            
                                
                            
                        </ul>
                    </div>
                </div>
            

            
                <div class="sidebox">
                    <div class="hd">
                        <h2 class="no-toc">Examples That Use This Component</h2>
                    </div>

                    <div class="bd">
                        <ul class="examples">
                            
                                
                            
                                
                            
                                
                            
                                
                                    <li data-description="Shows how to extend the base widget class, to create your own Widgets.">
                                        <a href="../widget/widget-extend.html">Extending the Base Widget Class</a>
                                    </li>
                                
                            
                                
                                    <li data-description="Creating an accessible menu button using the Focus Manager Node Plugin, Event&#x27;s delegation support and mouseenter event, along with the Overlay widget and Node&#x27;s support for the WAI-ARIA Roles and States.">
                                        <a href="../node-focusmanager/node-focusmanager-3.html">Accessible Menu Button</a>
                                    </li>
                                
                            
                                
                                    <li data-description="Use IO to request data over HTTP.">
                                        <a href="../io/get.html">HTTP GET to request data</a>
                                    </li>
                                
                            
                                
                                    <li data-description="Example Photo Browser application.">
                                        <a href="../dd/photo-browser.html">Photo Browser</a>
                                    </li>
                                
                            
                                
                                    <li data-description="Portal style example using Drag &amp; Drop Event Bubbling and Animation.">
                                        <a href="../dd/portal-drag.html">Portal Style Example</a>
                                    </li>
                                
                            
                        </ul>
                    </div>
                </div>
            
        </div>
    </div>
</div>

<script src="../assets/vendor/prettify/prettify-min.js"></script>
<script>prettyPrint();</script>

</body>
</html>
